package spectra.ee.web.bbs.service;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;

import com.ibatis.sqlmap.client.SqlMapClient;

import spectra.base.log.Logger;
import spectra.base.sql.ibatis.SqlMapperWeb;
import spectra.base.util.DateUtil;
import spectra.base.util.FileUtil;
import spectra.base.util.StringUtil;
import spectra.ee.web.WebPublic;
import spectra.ee.web.bbs.model.Bbs;
import spectra.ee.web.bbs.model.BbsAccount;
import spectra.ee.web.bbs.model.BbsAttach;
import spectra.ee.web.bbs.model.BbsComment;
import spectra.ee.web.bbs.model.BbsContents;
import spectra.ee.web.bbs.model.BbsInfo;

/**
 * 커뮤니티 관련 클래스.
 *
 * @author kmhan
 */
public class BbsServiceBase
{

    /** Logger객체. */
    private static Logger logger = Logger.getLoggerInstance(BbsServiceBase.class.getName());

    /** SqlMapClient 객체. */
    protected static SqlMapClient sqlMap = SqlMapperWeb.getSqlMapWebInstance();

    /**
     * 사용자 아이디로 커뮤니티 리스트를 가져오는 메소드이다.
     * @param domainId
     * @param accountId
     * @return
     */
    public List selectBbsInfoListByAccountId(String domainId, String accountId)
    {
        List list = null;
        try
        {
        	BbsInfo obj = new BbsInfo();
        	obj.setAccountId(accountId);
        	obj.setServiceType(WebPublic.SERVICE_TYPE_KB);
        	obj.setDomainId(domainId);
        	obj.setWebviewFlag(WebPublic.FLAG_Y);
 	 	
            list = (List)sqlMap.queryForList("Bbs.selectBbsInfoListByAccountId", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }
    
    /**
     * BBS_INFO_ID와 사용자 아이디로 커뮤니티 정보를 가져오는 메소드이다.
     * @param bbsInfoId
     * @param accountId
     * @return
     */
    public BbsInfo selectBbsInfoByAccountId(String bbsInfoId, String accountId)
    {
    	BbsInfo bbsInfo = null;
        try
        {
        	BbsInfo obj = new BbsInfo();
        	obj.setAccountId(accountId);
        	obj.setBbsInfoId(bbsInfoId);
        	obj.setWebviewFlag(WebPublic.FLAG_Y);
        	
        	bbsInfo = (BbsInfo)sqlMap.queryForObject("Bbs.selectBbsInfoByAccountId", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return bbsInfo;
    }
    
    /**
     * bbsInfoId로 커뮤니티 사용자 리스트를 가져오는 메소드이다.
     * @param bbsInfoId
     * @param authLevel
     * @return
     */
    public List selectBbsAccountListByBbsInfoId(String bbsInfoId, int authLevel)
    {
    	List list = null;
        try
        {  
        	BbsAccount obj = new BbsAccount();
        	obj.setBbsInfoId(bbsInfoId);
        	obj.setAuthLevel(authLevel);
            list = (List)sqlMap.queryForList("Bbs.selectBbsAccountListByBbsInfoId", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }
    
    /**
     * bbsInfoId로 옵션필드 정보를 가져오는 메소드이다.
     * @param bbsInfoId
     * @return
     */
    public List selectBbsOptionfieldByBbsInfoId(String bbsInfoId)
    {
        List list = null;
        try
        {        	 	 	
            list = (List)sqlMap.queryForList("Bbs.selectBbsOptionfieldByBbsInfoId", bbsInfoId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }
    
    /**
     * 커뮤니티를 입력하는 메소드이다.
     * @param obj
     * @return
     */
    public boolean insertBbs(Bbs obj)
    {
    	boolean result = false;
        try
        {
       	 	String currDate = DateUtil.getCurrDateTimeStamp();             
            sqlMap.startTransaction();
            
       	 	String bbsId = (String) sqlMap.queryForObject("Bbs.selectBbsIdNextKey", null);
       	 	obj.setBbsId(bbsId);
       	 	if (obj.getRefBbsId() == null || "".equals(obj.getRefBbsId()))
       	 		obj.setRefBbsId(bbsId);
       	 	int bbsNum = ((Integer) sqlMap.queryForObject("Bbs.selectBbsNumNextKey", obj.getBbsInfoId())).intValue();
       	 	obj.setBbsNum(bbsNum);
       	 	
       	 	// t_bbs 테이블에 insert
            sqlMap.insert("Bbs.insertBbs", obj);
            
            String[] arContents = StringUtil.splitContents(obj.getContents(), WebPublic.MAX_CONTENTS_LENGTH);
            
            // 내용입력
            BbsContents bbsContentsObj = null;
            for (int i=0; i<arContents.length; i++)
            {
            	bbsContentsObj = new BbsContents();
            	bbsContentsObj.setBbsId(bbsId);
            	bbsContentsObj.setContentsSeq(i);
            	bbsContentsObj.setContents(arContents[i]);
            	bbsContentsObj.setCreatedDate(currDate);
	            // t_bbs_contents에 insert
	            sqlMap.insert("Bbs.insertBbsContents", bbsContentsObj);
            }
            
            // 첨부파일이 있다면 입력
            List attachList = obj.getAttachList();
            if (attachList != null && attachList.size() > 0)
            {
            	for (int i=0; i<attachList.size(); i++)
            	{
            		BbsAttach attachObj = (BbsAttach) attachList.get(i);
            		attachObj.setBbsId(bbsId);
            		attachObj.setAttachSeq(i);
            		attachObj.setAttachExt(FileUtil.getFileExt(attachObj.getAttachName()));
            		attachObj.setCreatedBy(obj.getCreatedBy());
            		attachObj.setCreatedDate(currDate);
            		sqlMap.insert("Bbs.insertBbsAttach", attachObj);
            	}
            }
            sqlMap.commitTransaction();
            result = true;
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }   
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }    
    
    /**
     * 커뮤니티를 수정하는 메소드이다.
     * @param obj
     * @return
     */
    public boolean updateBbs(Bbs obj)
    {
    	boolean result = false;
        try
        {
       	 	String currDate = DateUtil.getCurrDateTimeStamp();             
            sqlMap.startTransaction();
                   	 	
       	 	// t_bbs 테이블에 update
            sqlMap.update("Bbs.updateBbsByPK", obj);
            
            String[] arContents = StringUtil.splitContents(obj.getContents(), WebPublic.MAX_CONTENTS_LENGTH);
            
            sqlMap.delete("Bbs.deleteBbsContentsByBbsId", obj.getBbsId());
            
            // 내용입력
            BbsContents bbsContentsObj = null;
            for (int i=0; i<arContents.length; i++)
            {
            	bbsContentsObj = new BbsContents();
            	bbsContentsObj.setBbsId(obj.getBbsId());
            	bbsContentsObj.setContentsSeq(i);
            	bbsContentsObj.setContents(arContents[i]);
            	bbsContentsObj.setCreatedDate(currDate);
	            // t_bbs_contents에 insert
	            sqlMap.insert("Bbs.insertBbsContents", bbsContentsObj);
            }
            
            // 첨부파일 삭제
            sqlMap.delete("Bbs.deleteBbsAttachByBbsId", obj.getBbsId());
            
            // 첨부파일이 있다면 입력
            List attachList = obj.getAttachList();
            if (attachList != null && attachList.size() > 0)
            {
            	for (int i=0; i<attachList.size(); i++)
            	{
            		BbsAttach attachObj = (BbsAttach) attachList.get(i);
            		attachObj.setBbsId(obj.getBbsId());
            		attachObj.setAttachSeq(i);
            		attachObj.setAttachExt(FileUtil.getFileExt(attachObj.getAttachName()));
            		attachObj.setCreatedBy(obj.getUpdatedBy());
            		attachObj.setCreatedDate(currDate);
            		sqlMap.insert("Bbs.insertBbsAttach", attachObj);
            	}
            }
            sqlMap.commitTransaction();
            result = true;
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }   
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }    
    
    /**
     * 커뮤니티를 삭제하는 메소드이다.
     * 본인이 작성한 글이나 커뮤니티 운영자 권한으로만 삭제할 수 있다.
     * @param obj
     * @return
     */
    public boolean deleteBbs(Bbs obj)
    {
        boolean result = false;
        try
        {
        	String currDate = DateUtil.getCurrDateTimeStamp();
        	Bbs bbsObj = selectBbsByBbsId(obj.getBbsId());
        	// 등록한 계정과 수정한 계정이 같을 경우에만 삭제할 수 있다.
        	if (bbsObj.getCreatedBy().equals(obj.getUpdatedBy()))
        	{            
	            sqlMap.update("Bbs.updateBbsDeleteFlagByBbsId", obj);
	            return true;
        	}
        	// 관리자 권한일 경우 삭제 가능
        	List bbsAccountList = selectBbsAccountListByBbsInfoId(obj.getBbsInfoId(), WebPublic.BBS_AUTH_LEVEL_ADMIN);
        	if (bbsAccountList != null && bbsAccountList.size() > 0)
        	{
        		for (int i=0; i<bbsAccountList.size(); i++)
        		{
        			BbsAccount bbsAccountObj = (BbsAccount) bbsAccountList.get(i);
        			if (obj.getUpdatedBy().equals(bbsAccountObj.getAccountId()))
        			{
        				sqlMap.update("Bbs.updateBbsDeleteFlagByBbsId", obj);
        	            return true;
        			}
        		}
        	}
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return result;
    }
    
    /**
     * bbsInfoId로 커뮤니티 리스트를 가져오는 메소드이다.
     * @param pageNo
     * @param rowsPerPage
     * @param bbsInfoId
     * @param condition
     * @param searchText
     * @return
     */
    public List selectBbsList(int pageNo, int rowsPerPage, String bbsInfoId, String condition, String searchText)
    {
        List list = null;
        try
        {
        	Bbs obj = new Bbs();        	
        	obj.setBbsInfoId(bbsInfoId);
        	obj.setStartNo((pageNo-1) * rowsPerPage + 1);
       	 	obj.setEndNo(pageNo * rowsPerPage);
       	 	obj.setCondition(condition);
       	 	obj.setRowsPerPage(rowsPerPage);
    	 	if (searchText != null)
    	 	{
	 	   	 	searchText = searchText.replaceAll("_", "\\\\_"); // 쿼리 escape지정
	 		 	searchText = searchText.replaceAll("%", "\\\\%"); // 쿼리 escape지정
    	 	}
    	 	obj.setSearchText(searchText);    	 	
 	 	
            list = (List)sqlMap.queryForList("Bbs.selectBbsList", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }
    
    /**
     * bbsInfoId로 커뮤니티 글개수를 가져오는 메소드이다.
     * @param bbsInfoId
     * @param condition
     * @param searchText
     * @return
     */
    public int selectBbsListCount(String bbsInfoId, String condition, String searchText)
    {   	 
   	 	int iResult = 0;
   	 	Bbs obj = new Bbs();        	
   	 	obj.setBbsInfoId(bbsInfoId);
   	 	obj.setCondition(condition);
	 	if (searchText != null)
	 	{
	   	 	searchText = searchText.replaceAll("_", "\\\\_"); // 쿼리 escape지정
		 	searchText = searchText.replaceAll("%", "\\\\%"); // 쿼리 escape지정
	 	}
	 	obj.setSearchText(searchText);
	 	
        try
        {
        	iResult = ((Integer)sqlMap.queryForObject("Bbs.selectBbsListCount", obj)).intValue();
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return iResult;
    } 
    
    /**
     * bbsId로 커뮤니티 내용을 가져오는 메소드
     * @param bbsId
     * @return
     */
    public Bbs selectBbsByBbsId(String bbsId)
    {
    	Bbs bbsObj = null;
    	try
        {
    		bbsObj = (Bbs) sqlMap.queryForObject("Bbs.selectBbsByBbsId", bbsId);
    		if (bbsObj != null)
    		{
    			// 옵션필드 정보를 optionList에 넣기
    			for (int i=0; i<10; i++)
    			{
    				setOptionList(bbsObj, bbsObj.getOptionList(), i);
    			}
    			
    			// 커뮤니티 내용 가져오기
    			List bbsContentsList = selectBbsContentsByBbsId(bbsId);
          		
   		 		String contents = "";
   		 		String contentsAnswer = "";
   		 		for (Iterator itContents = bbsContentsList.iterator(); itContents.hasNext();)
   		 		{
   		 			BbsContents bbsContentsObj = (BbsContents) itContents.next();
   		 			contents += StringUtil.nvl(bbsContentsObj.getContents(), "");
   		 		}
   		 		bbsObj.setContents(contents);
   		 	
   		 		// 첨부파일 정보 가져오기
   		 		List bbsAttachList = selectBbsAttachByBbsId(bbsId);
   		 		if (bbsAttachList != null)
   		 			bbsObj.setAttachCount(bbsAttachList.size());
   		 		bbsObj.setAttachList(bbsAttachList);
    		}
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return bbsObj;
    }
    
    public List setOptionList(Bbs bbsObj, List optionList, int index)
    {    	
    	if (bbsObj != null && bbsObj.getOptionList() != null)
    	{
    		String optionValue = "";
			switch (index)
			{
				case 0 :
					optionValue = bbsObj.getOption01();
					break;    			
				case 1 :
					optionValue = bbsObj.getOption02();
					break;
				case 2 :
					optionValue = bbsObj.getOption03();
					break;
				case 3 :
					optionValue = bbsObj.getOption04();
					break;
				case 4 :
					optionValue = bbsObj.getOption05();
					break;
				case 5 :
					optionValue = bbsObj.getOption06();
					break;
				case 6 :
					optionValue = bbsObj.getOption07();
					break;
				case 7 :
					optionValue = bbsObj.getOption08();
					break;
				case 8 :
					optionValue = bbsObj.getOption09();
					break;
				case 9 :
					optionValue = bbsObj.getOption10();
					break;
			}
			
			bbsObj.getOptionList().add(index, StringUtil.nvl(optionValue, ""));
    	}
    	return optionList;
    }
    
    /**
     * 커뮤니티의 이전글 가져오는 메소드이다.
     * @param bbsInfoId
     * @param bbsId
     * @return
     */
    public Bbs selectPrevBbsByBbsId(String bbsInfoId, String bbsId)
    {
    	Bbs bbsObj = null;
    	try
        {
    		Bbs obj = new Bbs();
    		obj.setBbsInfoId(bbsInfoId);
    		obj.setBbsId(bbsId);
    		
    		bbsObj = (Bbs) sqlMap.queryForObject("Bbs.selectPrevBbsByBbsId", obj);    		
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return bbsObj;
    }
    
    /**
     * 커뮤니티의 윗글 가져오는 메소드이다.
     * @param bbsInfoId
     * @param bbsId
     * @return
     */
    public Bbs selectNextBbsByBbsId(String bbsInfoId, String bbsId)
    {
    	Bbs bbsObj = null;
    	try
        {
    		Bbs obj = new Bbs();
    		obj.setBbsInfoId(bbsInfoId);
    		obj.setBbsId(bbsId);
    		
    		bbsObj = (Bbs) sqlMap.queryForObject("Bbs.selectNextBbsByBbsId", obj);    		
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return bbsObj;
    }
    
    /**
     * bbsId로 커뮤니티 내용을 가져오는 메소드이다.
     * @param bbsId
     * @return
     */
    public List selectBbsContentsByBbsId(String bbsId)
    {
        List list = null;
        try
        {       	 	
            list = (List)sqlMap.queryForList("Bbs.selectBbsContentsByBbsId", bbsId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }
    
    /**
     * bbsId로 첨부파일 정보를 가져오는 메소드이다.
     * @param bbsId
     * @return
     */
    public List selectBbsAttachByBbsId(String bbsId)
    {
        List list = null;
        try
        {       	 	
            list = (List)sqlMap.queryForList("Bbs.selectBbsAttachByBbsId", bbsId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }
    
    /**
     * bbsId로 조회수를 업데이트 하는 메소드이다.
     * @param bbsId
     * @return
     */
    public boolean updateBbsHitCount(String bbsId)
    {
    	boolean result = false;        
        try
        {
            sqlMap.update("Bbs.updateBbsHitCount", bbsId);
            result = true;
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }         
        return result;
    }
    
    /**
     * 커뮤니티 덧글을 입력하는 메소드이다.
     * @param bbsId
     * @param accountId
     * @param clientIp
     * @param contents
     * @return
     */
    public boolean insertBbsComment(String bbsId, String createdBy, String accountName, String clientIp, String contents)
    {
    	boolean result = false;        
        try
        {
        	String currDate = DateUtil.getCurrDateTimeStamp();
        	
        	int seq = ((Integer) sqlMap.queryForObject("Bbs.selectBbsCommentNextKey", bbsId)).intValue();
        	        	
        	BbsComment obj = new BbsComment();
        	obj.setBbsId(bbsId);
        	obj.setSeq(seq);
        	obj.setAccountName(accountName);
        	obj.setDeleteFlag(WebPublic.FLAG_N);
        	obj.setClientIp(clientIp);
        	obj.setContents(contents);
        	obj.setCreatedBy(createdBy);
        	obj.setCreatedDate(currDate);
        	obj.setUpdatedBy(createdBy);
        	obj.setUpdatedDate(currDate);
            sqlMap.insert("Bbs.insertBbsComment", obj);
            result = true;
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }         
        return result;
    }
    
    /**
     * 커뮤니티 덧글을 수정하는 메소드이다.
     * @param bbsId
     * @param seq
     * @param accountId
     * @param accountName
     * @param clientIp
     * @param contents
     * @return
     */
    public boolean updateBbsComment(String bbsId, int seq, String accountId, String accountName, String clientIp, String contents)
    {
    	boolean result = false;        
        try
        {
        	String currDate = DateUtil.getCurrDateTimeStamp();
        	
        	BbsComment obj = new BbsComment();
        	obj.setBbsId(bbsId);
        	obj.setSeq(seq);
        	obj.setAccountName(accountName);
        	obj.setClientIp(clientIp);
        	obj.setContents(contents);        	
        	obj.setUpdatedBy(accountId);
        	obj.setUpdatedDate(currDate);
            sqlMap.insert("Bbs.updateBbsComment", obj);
            result = true;
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }         
        return result;
    }
    
    /**
     * 커뮤니티 덧글을 삭제하는 메소드이다.
     * @param bbsId
     * @param seq
     * @param accountId
     * @param clientIp
     * @return
     */
    public boolean deleteBbsComment(String bbsId, int seq, String accountId, String clientIp)
    {
    	boolean result = false;        
        try
        {
        	String currDate = DateUtil.getCurrDateTimeStamp();
        	
        	BbsComment obj = new BbsComment();
        	obj.setBbsId(bbsId);
        	obj.setSeq(seq);
        	obj.setClientIp(clientIp);        	
        	obj.setUpdatedBy(accountId);
        	obj.setUpdatedDate(currDate);
            sqlMap.insert("Bbs.updateBbsCommentDeleteFlag", obj);
            result = true;
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }         
        return result;
    }
        
    /**
     * bbsId로 커뮤니티 덧글내용을 가져오는 메소드이다.
     * @param bbsId
     * @return
     */
    public List selectBbsCommentListByBbsId(String bbsId)
    {
        List list = null;
        try
        {       	 	
            list = (List)sqlMap.queryForList("Bbs.selectBbsCommentListByBbsId", bbsId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }
    
}
